<template>
  <div class="main-layout-1">
    <div id="map" ref="map"></div>
    <div>
      <el-button @click="getCenter">getCenter</el-button>
      <el-button @click="setCenter">setCenter</el-button>
    </div>
    <div>
      <span>radius size:</span>
      <input type="range" min="1" max="50" step="1" v-model="radius" @change="radiusChange"/>
      <span>{{radius}}</span>
      &nbsp;&nbsp;&nbsp;
      <span>blur size:</span>
      <input type="range" min="1" max="50" step="1" v-model="blur" @change="blurChange"/>
      <span>{{blur}}</span>
      &nbsp;&nbsp;&nbsp;
      <span ref="coodBox"></span>
    </div>
    <div style="position: absolute;">
      <div id="popup" class="ol-popup">
        <div style="text-align: right">
          <a href="#" id="popup-closer" class="ol-popup-closer">X</a>
        </div>

        <div id="popup-content" class="popup-content"></div>
      </div>
      <div id="marker"></div>
      <div id="textInfo">我是测试文本</div>
      <img id="gifInfo" src="source/1.gif" width="64">
    </div>
    <el-checkbox-group v-model="checkList">
      <el-checkbox label="天地图影像图" @change="changImage"></el-checkbox>
      <el-checkbox label="天地图影像标注" @change="changText"></el-checkbox>
    </el-checkbox-group>

  </div>
</template>

<script>
  import 'ol/ol.css'
  import { Map, View, Overlay, Feature } from 'ol'
  import { defaults as defaultControls, FullScreen, MousePosition, OverviewMap, ScaleLine, ZoomSlider } from 'ol/control'
  // import Tile from 'ol/layer/Tile'
  import { Heatmap as HeatmapLayer, Tile as TileLayer, Image as ImageLayer, Vector as VectorLayer } from 'ol/layer';
  import { fromLonLat, toLonLat, transform, Projection } from 'ol/proj'
  // import OSM from 'ol/source/OSM'
  import { OSM, Vector as VectorSource, ImageStatic, XYZ } from 'ol/source'
  import KML from 'ol/format/KML';

  import Graticule from 'ol/layer/Graticule'; // 经纬线

  import { toStringHDMS } from "ol/coordinate";

  import { Polygon, MultiPolygon, Point } from 'ol/geom'
  import { Style, Fill, Stroke, Icon, Text } from 'ol/style'

  import areaGeo from '/@/source/ningxiaOutside.json'

  export default {
    name: 'tree',
    data () {
      return {
        map: null,
        radius: 5,
        blur: 15,
        checkList: [],
      }
    },
    mounted () {
      this.initMap()
    },
    methods: {
      /**
       * 初始化一个 openlayers 地图
       */
      initMap () {
        let target = 'map' //跟页面元素的 id 绑定来进行渲染

        // Graticule，地图上覆盖的网格标尺图层
        // HeatMap，热力图
        // Vector，矢量图
        // VectorImage，单张的矢量图层
        // VectorTile，矢量瓦片图层
        // WebGLPoints，WebGL渲染的海量点图层

        // 经纬线
        this.graticuleLayer = new Graticule({
          // the style to use for the lines, optional.
          strokeStyle: new Stroke({
            color: 'rgba(255,120,0,0.9)',
            width: 2,
            lineDash: [0.5, 4]
          }),
          showLabels: true,
          wrapX: false
        })

        // 热力图
        this.heatmapLayer = new HeatmapLayer({
          source: new VectorSource({
            url: '/source/2012_Earthquakes_Mag5.kml',
            format: new KML({
              extractStyles: false
            })
          }),
          blur: parseInt(this.blur, 10),
          radius: parseInt(this.radius, 10),
          weight: function(feature) {
            var name = feature.get('name');
            var magnitude = parseFloat(name.substr(2));
            return magnitude - 5;
          }
        })

        // 单张图片的矢量图层

        let tileLayer = [
          new TileLayer({
            source: new OSM(),
            // source: new XYZ({
            //   url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            // }),
          }),
          this.graticuleLayer,
          this.heatmapLayer,
        ]
        let view = new View({
          // center 设置默认地图中心点位置 ，fromLonLat 函数是将给定的坐标从4326转到3857坐标系下，
          // 4326即是WGS84坐标系！（后面单独讲解 4326 和3857 坐标系的区别）
          // gis 默认使用 EPSG:3857 投影（墨卡托投影）
          center: fromLonLat([106.21467, 38.47954]),
          resolution: 2000, // 初始米/每像素，使用了该属性后 zoom 属性将不生效
          // zoom: 5, // 初始缩放级别
          constrainResolution: true, // 视图始终以最接近的整数缩放级别显示，这样可以避免视图（文字）模糊。false表示允许小数缩放级别
        })

        this.map = new Map({
          target: target, //绑定dom元素进行渲染
          layers: tileLayer, //配置地图数据源
          view: view, //配置地图显示的options配置（坐标系，中心点，缩放级别等）
          controls: defaultControls().extend([
            new FullScreen(),
            // new MousePosition({
            //   coordinateFormat (cood) {
            //     return cood.map(item => item.toFixed(5))
            //   },
            //   projection: "EPSG:4326",
            //   className: 'test',
            // }),
            new OverviewMap({
              layers: [
                new TileLayer({
                  source: new OSM(),
                  // source: new XYZ({
                  //   url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
                  // }),
                })
              ]
            }),
            // new ScaleLine(),
            new ZoomSlider(),
          ])
        })

        // this.map.addControl(new FullScreen())

        this.view = view

        this.addRouteLayer()

        this.addPopup()

        this.addMarker([106.21467, 38.47954])
        this.addText([106.17851, 38.47844], '我是测试')
        this.addGif([106.19895, 38.47555])

        this.addPoints([
          { coord: [106.03889, 37.42267], color: 'red' },
          { coord: [105.64338, 36.56716], color: 'pink' },
          { coord: [106.56623, 37.42267], color: 'blue' },
          { coord: [106.23658, 36.01142], color: 'yellow' },
        ])
      },
      addRouteLayer () {
        let features = []
        let routeFeature = []
        areaGeo.forEach(g => {
          let lineData = g.features[0];
          if (lineData.geometry.type == "MultiPolygon") {
            const geometry = new MultiPolygon(
              lineData.geometry.coordinates
            ).transform("EPSG:4326", "EPSG:3857")
            this.geometry = geometry
            // this.geometryExtent = geometry.getExtent()
            routeFeature = new Feature({
              geometry: geometry
            });
          } else if (lineData.geometry.type == "Polygon") {
            routeFeature = new Feature({
              geometry: new Polygon(
                lineData.geometry.coordinates
              ).transform("EPSG:4326", "EPSG:3857")
            });
          }
        })
        routeFeature.setStyle(new Style({
          fill: new Fill({
            color: [71, 137, 227, 0.3]
          }),
          stroke: new Stroke({
            width: 3,
            color: [71, 137, 227, 1],
          })
        }))
        features.push(routeFeature);


        const imgFeature = new Feature({
          geometry: new Point(
            fromLonLat([105.18196, 37.50987])
          ),
          style (a, b) {
            console.log(a, b)
          },
        })
        imgFeature.setStyle(this.getIcon())
        features.push(imgFeature);

        const textFeature = new Feature({
          geometry: new Point(
            fromLonLat([105.18196, 37.50987])
          ),
        })
        textFeature.setStyle(this.getText())
        features.push(textFeature)

        let routeLayer = new VectorLayer({
          source: new VectorSource({
            features: features //这里的features就是矢量图层
          }),
        });

        // 添加图层到地图上
        this.map.addLayer(routeLayer);

        this.view.fit(this.geometry)
      },
      addPoints (coords) {
        const features = []
        this.pointLayer = new VectorLayer({
          source: new VectorSource(),
        })
        this.map.addLayer(this.pointLayer)
        coords.forEach(coordInfo => {
          console.log(coordInfo)
          let feature = new Feature({
            geometry: new Point(fromLonLat(coordInfo.coord))
          })
          feature.setStyle(this.getIcon1(coordInfo.color))
          features.push(feature)
        })
        this.pointLayer.getSource().addFeatures(features)
      },
      getIcon1 (color) {
        console.log(color)
        return new Style({
          image: new Icon({
            src: 'source/marker.png',
            anchor: [1, 1],
            color,
          })
        })
      },
      getIcon () {
        var styleIcon = new Style({
          image: new Icon({
            src: 'ice-cream.svg',
          }),
        })
        return styleIcon
      },
      getText () {
        var text = new Style({
          text: new Text({
            text: '你好！哈哈哈！！！',
            fill: new Fill({
              color: 'red',
            }),
            font: '30px Calibri,sans-serif',
            stroke: new Stroke({
              color: 'green',
              width: 2,
            })
          })
        })
        return text
      },
      addPopup() {
        // 使用变量存储弹窗所需的 DOM 对象
        var container = document.getElementById("popup");
        var closer = document.getElementById("popup-closer");
        var content = document.getElementById("popup-content");

        // 创建一个弹窗 Overlay 对象
        this.overlay = new Overlay({
          element: container, // 绑定 Overlay 对象和 DOM 对象的
          autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
          autoPanAnimation: {
            duration: 250 // 自动平移效果的动画时间 9毫秒）
          }
        });
        // 将弹窗添加到 map 地图中
        this.map.addOverlay(this.overlay);

        /**
         * 为弹窗添加一个响应关闭的函数
         */
        closer.onclick = () => {
          this.overlay.setPosition(undefined);
          closer.blur();
          return false;
        };
        /**
         * 添加单击map 响应函数来处理弹窗动作
         */
        this.map.on("singleclick", evt => {
          let coordinate = transform(
            evt.coordinate,
            "EPSG:3857",
            "EPSG:4326"
          );
          // 点击尺 （这里是尺(米)，并不是经纬度）;
          let hdms = toStringHDMS(toLonLat(evt.coordinate)); // 转换为经纬度显示
          console.log(evt.coordinate, coordinate, toLonLat(evt.coordinate), hdms);
          content.innerHTML = `
            <p>你点击了这里：</p>
            <p>经纬度：<p><code> ${hdms}  </code> <p>
            <p>坐标：</p>X：${coordinate[0].toFixed(5)} &nbsp;&nbsp; Y: ${coordinate[1].toFixed(5)}
          `;
          this.overlay.setPosition(evt.coordinate); //把 overlay 显示到指定的 x,y坐标
        });
      },
      addMarker(cood) {
        const marker = new Overlay({
          position: fromLonLat(cood),
          positioning: "center-center",
          element: document.getElementById("marker"),
          stopEvent: false
        });
        this.map.addOverlay(marker);
      },
      addText (cood) {
        const textInfo = new Overlay({
          position: fromLonLat(cood),
          offset: [0, 0],
          element: document.getElementById('textInfo')
        })
        this.map.addOverlay(textInfo)
      },
      addGif (cood) {
        const gifInfo = new Overlay({
          position: fromLonLat(cood),
          element: document.getElementById('gifInfo')
        })
        this.map.addOverlay(gifInfo)
      },
      getCenter () {
        console.log(this.view) // 获取视图分辨率。
      },
      setCenter () {
        this.view.setCenter(fromLonLat([106.21467, 38.47954]))
      },
      radiusChange () {
        this.heatmapLayer.setBlur(parseInt(this.radius, 10))
      },
      blurChange () {
        this.heatmapLayer.setBlur(parseInt(this.blur, 10))
      },
      changImage (checked, e) {
        if (checked) {
          this.tiandiMap_img = new TileLayer({
            name: '天地图影像',
            source: new XYZ({
              url: 'http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d',
              wrapX: false,
            })
          })

          this.map.addLayer(this.tiandiMap_img)
        } else {
          console.log('remove', this.tiandiMap_img)
          this.map.removeLayer(this.tiandiMap_img)
        }
      },
      changText (checked, e) {
        if (checked) {
          this.tiandiMap_cia = new TileLayer({
            name: '天地图注解',
            source: new XYZ({
              url: 'http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d',
              wrapX: false,
            })
          })
          this.map.addLayer(this.tiandiMap_cia)
        } else {
          this.map.removeLayer(this.tiandiMap_cia)
        }
      },
    },
  }
</script>
<style lang="scss" scoped>
  #map {
    width: 100%;
    height: 100%;
  }
  .ol-popup {
    border-radius: 4px;
    padding: 8px;
    background: rgba(255, 255, 255, 0.85);
  }
  #marker {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: red;
  }
  #textInfo {
    color: yellow;
    font-weight: bold;
    background: orange;
  }
</style>
